import { Image, ScrollView, Textarea, View } from '@tarojs/components';
import { eventCenter, getCurrentInstance } from "@tarojs/runtime";
import Taro from '@tarojs/taro';
import { useEffect, useState } from "react";
import data, { globalWsHost } from '../../util/data';
import CustomSocket from '../../util/socket';
import './index.less';
import PaintItem from './item';
import { createImgMessage, createMjRequest, createMjSubmitChangeRequest, MJApiPath, MJSubmitResp, paintDefaultMessage, PaintMessage, TaskStatus } from './msg';

let socket = new CustomSocket(globalWsHost)
const sendButtonImg = require('../../assert/Paint_Icon_Send.png')

const PaintChat = ({ tabBarHeight = 60 }) => {
	const [historyMsgList, setHistoryMsgList] = useState<PaintMessage[]>([]);
	const [messageContent, setMessageContent] = useState('');
	const [lastMessageContent, setLastMessageContent] = useState('');
	const [scrollHeight, setScrollHeight] = useState('100vh');
	const [inputBottom, setInputBottom] = useState(0);
	const [isLoading, setIsLoading] = useState(false);
	const [textAreaHeight, setTextAreaHeight] = useState(40);
	const [toViewId, setToViewId] = useState('')
	const [moveTime, setMoveTime] = useState(1);

	const onReady = () => {
		loadHistoryMsgList();
		setToViewId('placeholderItem')
		console.log('paint ready...')
	}

	const onShow = () => {
		console.log('on paint chat show...');
		socket.onSocketMessage(updateMessage);
		if (data.pageShareInfo.makeSamePrompt !== '') {
			setMessageContent(data.pageShareInfo.makeSamePrompt)
			data.pageShareInfo.makeSamePrompt = ''
		}
	}

	useEffect(() => {
		// 注册一个事件处理函数，当页面Ready时调用onReady函数
		const onReadyEventId = getCurrentInstance().router?.onReady
		eventCenter.on(onReadyEventId ? onReadyEventId : "空ID", onReady, this)
		const onShowEventId = getCurrentInstance().router?.onShow
		eventCenter.on(onShowEventId ? onShowEventId : "空ID", onShow, this)

		if (socket && socket.socketOpen) { // 如果socket已经连接并打开，直接返回
			console.log('socket已经连接并打开')
			return
		}

		return () => { // 组件卸载时执行
			console.log('清理paint')
			setHistoryMsgList([])
			setIsLoading(false)
		}
	}, [])

	const handleMessageSubmit = (isRefresh: boolean) => {
		if (isLoading) return
		if (!isRefresh && messageContent && messageContent.trim() !== '') {
			setLastMessageContent(messageContent.trim())
		}
		setLastMessageContent(lastMsgContent => {
			if (lastMsgContent && lastMsgContent.trim() !== '') {
				setIsLoading(true);
				setMessageContent(''); // 清空输入的消息内容

				// 先添加占位一个空消息，等待服务端响应
				setHistoryMsgList(prev => prev.concat(createImgMessage('placeholder', lastMsgContent.trim())));
				// startTimeoutListen()

				socket.sendMjMessage(createMjRequest(MJApiPath.SUBMIT, lastMsgContent.trim()));
				// test mock
				// console.log('发送消息')
				// const json1000Str = '{"code": 1000,"errMsg": "", "taskId": "8806965296649814","progress": 93,"imageUrl": "http://ys-aigc.oss-cn-beijing.aliyuncs.com/mj/Kt4Ozh.jpg?x-oss-process=image/resize,w_512/quality,q_50"}';
				// updateMessage(json1000Str);
				// const json1001Str = '{"code": 1001,"errMsg": "", "taskId": "8806965296649814","progress": 98,"imageUrl": "http://ys-aigc.oss-cn-beijing.aliyuncs.com/mj/Kt4Ozh.jpg?x-oss-process=image/resize,w_512/quality,q_50"}';
				// updateMessage(json1001Str);
				// setTimeout(() => {
				// 	const json1200Str = '{"code": 1001,"errMsg": "", "taskId": "7806965296649814","progress": 99,"imageUrl": "http://ys-aigc.oss-cn-beijing.aliyuncs.com/mj/Kt4Ozh.jpg?x-oss-process=image/resize,w_512/quality,q_50"}';
				// 	updateMessage(json1200Str);
				// }, 15 * 1000)
			}
			return lastMsgContent;
		})
	}

	const updateMessage = (msg: string) => {
		console.log('收到消息：', msg)
		let msgResp = JSON.parse(msg) as MJSubmitResp
		switch (msgResp.code) {
			case TaskStatus.EXCEPTION01:
			case TaskStatus.EXCEPTION02:
			case TaskStatus.EXCEPTION03:
				exceptionMsgHandle(msgResp)
				return;
			case TaskStatus.IDLE: // 提交成功，但不保存
				console.log('任务提交成功的消息响应: ', msg)
				submitSuccessHandle(msgResp)
			case TaskStatus.PROCESSIN: // 进度更新，保存
				updateImageResult(msgResp)
			case TaskStatus.FINISH: // 更新图片结果，保存
				updateImageResult(msgResp)
				return
		}
		updateScrollTop()
	}

	const exceptionMsgHandle = (msgResp: MJSubmitResp) => {
		setHistoryMsgList(historyMsgList => {
			if (historyMsgList.length === 0) return historyMsgList
			// 找到最后一个占位消息，替换为正式消息数据
			let prevElement = historyMsgList[historyMsgList.length - 1]
			prevElement.prompt = msgResp.errMsg
			prevElement.image = ''
			historyMsgList = historyMsgList.slice(0, historyMsgList.length - 1).concat(prevElement)
			return historyMsgList
		});
		setIsLoading(false)
	}

	const submitSuccessHandle = (msgResp: MJSubmitResp) => {
		setHistoryMsgList(historyMsgList => {
			if (historyMsgList.length === 0) return historyMsgList
			// 找到最后一个占位消息，替换为正式消息数据
			let prevElement = historyMsgList[historyMsgList.length - 1]
			if (msgResp.taskId !== '') {
				prevElement.taskId = msgResp.taskId
				prevElement.status = msgResp.code
			}
			historyMsgList = historyMsgList.slice(0, historyMsgList.length - 1).concat(prevElement)
			return historyMsgList
		});
	}

	const updateImageResult = (msgResp: MJSubmitResp) => {
		setHistoryMsgList(historyMsgList => {
			if (historyMsgList.length === 0) return historyMsgList
			// 找到最后一个占位消息，替换为正式消息数据
			let prevElement = historyMsgList[historyMsgList.length - 1]
			if (prevElement.taskId !== msgResp.taskId) {
				// 当前端超时后，用户发了新消息，此时服务器可能推送旧作品更新消息，则不处理
				console.log('旧消息抛弃')
				return historyMsgList
			}

			if (msgResp.imageUrl !== '') {
				prevElement.taskId = msgResp.taskId
				prevElement.image = msgResp.imageUrl
				prevElement.imageProgess = msgResp.progress
				prevElement.isLoading = true
				prevElement.status = msgResp.code
				saveHistoryMsgList()
			}
			if (msgResp.code === 1200) {
				setIsLoading(false);
				prevElement.isLoading = false
			}
			historyMsgList = historyMsgList.slice(0, historyMsgList.length - 1).concat(prevElement)
			updateScrollTop()
			return historyMsgList
		});
	}

	const startTimeoutListen = () => {
		setIsLoading(prev => {
			setTimeout(() => {
				console.log('发消息后超时监听')
				if (prev) { setIsLoading(false); }
			}, 5 * 60 * 1000)
			return prev
		})
	}

	const saveHistoryMsgList = () => {
		setHistoryMsgList(prev => {
			Taro.setStorage({
				key: 'historyMsgList', data: prev,
				success: function () { console.log('数据存储成功'); },
				fail: function () { console.log('数据存储失败'); }
			})
			return prev;
		})
	}

	const loadHistoryMsgList = () => {
		setHistoryMsgList(prev => {
			let localRecord = Taro.getStorageSync('historyMsgList') as PaintMessage[];
			console.log('本地缓存的历史消息列表：', localRecord);
			if (localRecord) { // 检查一次云端是否成功了
				localRecord = localRecord.filter((item) => {
					if (item.status === TaskStatus.PROCESSIN) {
						setIsLoading(true)
					}
					return item.status !== TaskStatus.IDLE
				})
				return localRecord;
			}
			return prev.concat(paintDefaultMessage)
		})
		updateScrollTop()
	}

	const updateScrollTop = () => {
		setHistoryMsgList(prev => {
			setToViewId('item' + historyMsgList.length)
			return prev
		})
		setMoveTime(prev => prev + 1)
	}

	const handleLineChange = (event) => {
		setTextAreaHeight(event.detail.height)
	}

	const handleKeyboardHeightChange = (e) => {
		setInputBottom(e.detail.height === 0 ? e.detail.height : e.detail.height - tabBarHeight - 25);
	}

	const handleFocus = (e) => {
		// setAddMediaModal(false);
		setInputBottom(e.detail.height === 0 ? e.detail.height : e.detail.height - tabBarHeight - 25);
	}

	const handleBlur = () => {
		const scrollHeight = '100vh';
		setScrollHeight(scrollHeight);
		setInputBottom(0);
	}

	const handleInput = (e) => {
		setMessageContent(e.detail.value);
	}

	const formatMessages = () => {
		return historyMsgList.length > 0 ? historyMsgList : [];
	}

	const refreshGenerate = () => {
		if (historyMsgList.length > 2) {
			setLastMessageContent(historyMsgList[historyMsgList.length - 2].content);
		}
		handleMessageSubmit(true)
	}

	const btnU = (item: PaintMessage, idx: number) => {
		// https://ys-aigc.oss-cn-beijing.aliyuncs.com/mj/W4iJLC.jpg?x-oss-process=image/resize,w_512/quality,q_50/crop,w_256,y_256,g_nw
		let newImageUrl = ''
		switch (idx) {
			case 1:
				console.log('左上放大')
				newImageUrl = item.image.split("?")[0] + "?x-oss-process=image/crop,w_1024,h_1024,y_0,g_nw"
				break
			case 2:
				console.log('右上放大')
				newImageUrl = item.image.split("?")[0] + "?x-oss-process=image/crop,w_1024,h_1024,x_1024,g_nw"
				break
			case 3:
				console.log('左下放大')
				newImageUrl = item.image.split("?")[0] + "?x-oss-process=image/crop,w_1024,h_1024,y_1024,g_nw"
				break
			case 4:
				console.log('右下放大')
				newImageUrl = item.image.split("?")[0] + "?x-oss-process=image/crop,w_1024,h_1024,x_1024,y_1024,g_nw"
				break
		}
		console.log("U选择后的图片url：", newImageUrl)
		let message = createImgMessage(newImageUrl, item.prompt)
		message.imageType = idx
		message.imageProgess = 100
		setHistoryMsgList((prev) => prev.concat(message))
		saveHistoryMsgList()
		startTimeoutListen()
	}

	const btnV = (item: PaintMessage, idx: number) => {
		console.log("V选择的idx：", idx, "之前的任务信息：", item.taskId)
		setIsLoading(true);
		updateScrollTop()
		// 先添加占位一个空消息，等待服务端响应
		setHistoryMsgList(prev => prev.concat(createImgMessage('placeholder', item.prompt)));

		socket.sendMjMessage(createMjSubmitChangeRequest(item.taskId, idx));
	}

	const onItemTimeout = () => {
		// 存在重新小程序打断生成过程的情况，要通过初始化加载本地识别并阻断发送
		setIsLoading(false)
		saveHistoryMsgList()
	}

	return (
		<View className='im-page'>
			{/* <View> scrollIntoView={toViewId} */}
			<ScrollView className='paint-container' style={{ width: '100%', height: scrollHeight, paddingTop: '10px' }} enableFlex enableBackToTop scrollY scrollIntoView={toViewId} scrollIntoViewAlignment='start'>
				{formatMessages().map((item, index) => {
					return (<PaintItem id={'item' + index} item={item} btnU={btnU} btnV={btnV} onTimeout={onItemTimeout} />);
				})}
				<View className='placeholder-box' id='placeholderItem' style={{ width: '100%', height: '30vw' }} />
			</ScrollView>
			{/* </View> */}
			<View className='im-toolbar' style={{ bottom: inputBottom }}>
				<Textarea
					style={{ height: `${textAreaHeight}px` }}
					placeholder={isLoading ? '正在生成...' : '请输入你想要的画面描述'}
					placeholderStyle='color: #8b8e94;'
					showConfirmBar={false}
					maxlength={1000}
					disabled={isLoading}
					value={messageContent}
					adjustPosition={true}
					adjust-keyboard-to='false'
					confirmType='send'
					onKeyboardHeightChange={handleKeyboardHeightChange}
					onFocus={handleFocus}
					onBlur={handleBlur}
					onInput={handleInput}
					onConfirm={() => handleMessageSubmit(false)}
					onLineChange={handleLineChange}
				/>
				<Image className="send-button" src={sendButtonImg} mode="aspectFit" onClick={() => handleMessageSubmit(false)} style={{ width: '30px', height: '30px', opacity: isLoading ? '0.5' : '1' }} />
			</View>

		</View>
	);
}

export default PaintChat
